﻿/*
 * protocolmasters.cpp
 *
 *  Created on: 2017年8月27日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_OS_PROTOCOL DM_API_EXPORT

#include <dm/os/protocol/protocolmasters.hpp>
#include <dm/os/log/logger.hpp>

namespace dm{
namespace os{
namespace protocol{

static const char* logModule = "CProtocolMasters.protocol.os.dm";

CProtocolMasters::CProtocolMasters():CProtocolMasterBase(),m_devCnt(0),m_devAgents(NULL),m_curDev(-1){
	enableAnswerMsgCheck(true);
	enableRequestMsgCheck(true);
	log().debug(THISMODULE "创建对象");
}

CProtocolMasters::~CProtocolMasters(){
	log().debug(THISMODULE "销毁对象");
	if( m_devAgents!=NULL )
		delete [] m_devAgents;
}

void CProtocolMasters::setDeviceCount( const int& cnt ){
	if( m_devAgents!=NULL ){
		delete [] m_devAgents;
	}

	if( cnt>0 ){
		m_devAgents = new dm::scada::CDeviceAgent[cnt];
		m_devCnt = cnt;
	}else{
		log().debug(THISMODULE "设置设备数为0");
		m_devAgents = NULL;
		m_devCnt = 0;
	}

	m_curDev = -1;
}

bool CProtocolMasters::setDevice( const char* name,const int& idx ){
	if( idx<0 ){
		log().warnning(THISMODULE "参数错误 idx:%d",idx);
		return false;
	}

	if( idx>=m_devCnt ){
		log().warnning(THISMODULE "参数idx(%d)超出范围(%d",idx,m_devCnt);
		return false;
	}

	return m_devAgents[idx].setByName(name);
}

bool CProtocolMasters::setDevice( const char* name,const int& idx,const dm::scada::CDeviceAgent::SSignalsSize& size ){
	if( idx<0 ){
		log().warnning(THISMODULE "参数错误 idx:%d",idx);
		return false;
	}

	if( idx>=m_devCnt ){
		log().warnning(THISMODULE "参数idx(%d)超出范围(%d",idx,m_devCnt);
		return false;
	}

	return m_devAgents[idx].setByName(name,size,true);
}

bool CProtocolMasters::setDevice( const int& id,const int& idx,const dm::scada::CDeviceAgent::SSignalsSize& size ){
	if( idx<0 ){
		log().warnning(THISMODULE "参数错误 idx:%d",idx);
		return false;
	}

	if( idx>=m_devCnt ){
		log().warnning(THISMODULE "参数idx(%d)超出范围(%d",idx,m_devCnt);
		return false;
	}

	return m_devAgents[idx].setById(id,size,true);
}

bool CProtocolMasters::setDevice( const int& id,const int& idx ){
	if( idx<0 ){
		log().warnning(THISMODULE "参数错误 idx:%d",idx);
		return false;
	}

	if( idx>=m_devCnt ){
		log().warnning(THISMODULE "参数idx(%d)超出范围(%d",idx,m_devCnt);
		return false;
	}

	return m_devAgents[idx].setById(id);
}

dm::scada::CDeviceAgent* CProtocolMasters::getDeviceAgent( int idx ){
	if( idx<0 || idx>=m_devCnt )
		return NULL;

	return m_devAgents+idx;
}

const dm::scada::CDeviceAgent* CProtocolMasters::getDeviceAgent( int idx )const{
	if( idx<0 || idx>=m_devCnt )
		return NULL;

	return m_devAgents+idx;
}

void CProtocolMasters::setCurDev( int index ){
	if( index>=m_devCnt || index<0 ){
		m_curDev = -1;
	}else
		m_curDev = index;
}

bool CProtocolMasters::isLocalRemoteCtl( const dm::msg::index_t& idx )const{
	return getDevIndexByRemoteCtl(idx)!=-1;
}

bool CProtocolMasters::isLocalPara( const dm::msg::index_t& idx )const{
	return getDevIndexByPara(idx)!=-1;
}

int CProtocolMasters::getDevIndexByRemoteCtl( const dm::msg::index_t& idx )const{
	for( int i=0;i<m_devCnt;++i ){
		if( m_devAgents[i].isMyRemoteCtl(idx) )
			return i;
	}

	return -1;
}

int CProtocolMasters::getDevIndexByPara( const dm::msg::index_t& idx )const{
	for( int i=0;i<m_devCnt;++i ){
		if( m_devAgents[i].isMyParameter(idx) )
			return i;
	}

	return -1;
}

void CProtocolMasters::onLinkSettled( const ts_t& ts,const rts_t& rts ){
	for( int i=0;i<m_devCnt;++i ){
		if( m_devAgents[i].state() )
			m_devAgents[i].state()->updateState(dm::scada::CDeviceState::ESComConnted,rts);
	}


	CProtocolMasterBase::onLinkSettled(ts,rts);
}

void CProtocolMasters::onLinkClosed( const ts_t& ts,const rts_t& rts ){
	for( int i=0;i<m_devCnt;++i ){
		if( m_devAgents[i].state() )
			m_devAgents[i].state()->updateState(dm::scada::CDeviceState::ESComDiscon,rts);
	}

	CProtocolMasterBase::onLinkClosed(ts,rts);
}

void CProtocolMasters::updateRecvTime( dm::uint32 bytes,const rts_t& rts){
	if( m_devCnt>0 ){
		if( m_curDev<0 ){
			// 认为是广播过来的数据
			for( int i=0;i<m_devCnt;++i ){
				if( m_devAgents[i].state() )
					m_devAgents[i].state()->rxed(bytes,rts);
			}
		}else if( m_curDev<m_devCnt ){
			if( m_devAgents[m_curDev].state() ){
				m_devAgents[m_curDev].state()->rxed(bytes,rts);
				m_devAgents[m_curDev].state()->updateState(dm::scada::CDeviceState::ESComConnted,rts);
			}
		}
	}

	CProtocolMasterBase::updateRecvTime(bytes,rts);
}

void CProtocolMasters::updateSendTime( dm::uint32 bytes,const rts_t& rts ){
	if( m_devCnt>0 ){
		if( m_curDev<0 ){
			for( int i=0;i<m_devCnt;++i ){
				if( m_devAgents[i].state() )
					m_devAgents[i].state()->txed(bytes,rts);
			}
		}else if( m_curDev<m_devCnt ){
			if( m_devAgents[m_curDev].state() )
				m_devAgents[m_curDev].state()->txed(bytes,rts);
		}
	}

	CProtocolMasterBase::updateSendTime(bytes,rts);
}

}
}
}
